package com.easylinkin.linkappapi.elasticsearch.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.easylinkin.linkappapi.common.model.RequestModel;
import com.easylinkin.linkappapi.common.model.SortModel;
import com.easylinkin.linkappapi.device.entity.vo.DeviceQueryVo;
import com.easylinkin.linkappapi.elasticsearch.entity.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.springframework.scheduling.annotation.Scheduled;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * ES 相关的业务接口
 * </p>
 *
 * @author XuGuoQing
 * @since 2020-04-15
 */
public interface IEService extends IService<DeviceEnergyReal> {

    EsHistogramResponseModel histogramStatistic(EsQuerymodel queryModel) throws JsonProcessingException, ParseException;

    SearchHits getDeviceDataListFromES(String deviceCode, Long projectId, int index, int size, String beginTime, String endTime, List<String> necessaryFieldList, List<SortModel> sorts);

    SearchHits getDeviceDataListFromESByDeviceName(Map<String, String> likeQueryMap,
                                                   int index, int size, String beginTime,
                                                   String endTime, List<String> necessaryFieldList, String indices);

    SearchResponse getDeviceFlowListFromES(Map<String, Object> likeQueryMap,
                                           int index, int size, TimeRange timeRange,
                                           List<String> necessaryFieldList,
                                           SortField sortField,
                                           TermsAggregationBuilder termsAggregationBuilder);

    SearchResponse getDeviceFlowListFromES(Map<String, Object> likeQueryMap,
                                           int index, int size, TimeRange timeRange,
                                           List<String> necessaryFieldList,
                                           SortField sortField,
                                           TermsAggregationBuilder termsAggregationBuilder, String indices);

    SearchResponse getScrollData(String scrollId) throws IOException;

    SearchHits getHistoricDataCurrDay(String projectId, String deviceCode, String gteString, String lteString, String selectFields);

    /**
     * 根据数据源id 和 类型（水、电、气）来查询设备编码集合
     *
     * @param dataSourceId 数据源id
     * @return 设备编码集合
     */
    List<String> getDeviceCodes(String dataSourceId);

    DeviceEnergyReal getRealDevicePage(EsQuerymodel queryModel, EsResponsemodel esResponsemodel, Page page) throws JsonProcessingException;

    MomStatisticModel getMomStatisticData(EsQuerymodel queryModel) throws JsonProcessingException, ParseException;


    void exportBankExcel(String useKinds, HttpServletRequest request, HttpServletResponse response);

    /**
     * 从ES 获取设备历史数据
     */
    Map<String, List<DeviceEnergyReal>> getDeviceHistoricDataFromES(EsQuerymodel queryModel) throws JsonProcessingException;

    /**
     * 导出能耗报表
     */
    void exportEnergyReport(EsQuerymodel queryModel, HttpServletRequest request, HttpServletResponse response) throws IOException;

    /**
     * 从查询结果解析结果
     *
     * @param results es 查询命中
     * @return 解析后的结果集
     */
    List<Map<String, Object>> parseResultFromSearchHit(SearchHit[] results);

    /**
     * 日 周 月 统计
     */
    DayWeekMonthStatisticModel dayWeekMonthStatistic(EsQuerymodel esQuerymodel);

    /**
     * 自定义时间 能耗统计查询
     *
     * @param esQuerymodel 查询参数
     */
    CustomPeriodStatisticModel customPeriodStatistic(EsQuerymodel esQuerymodel);

    /**
     * 自定义时间 能耗统计查询 控制器用
     *
     * @param esQuerymodel 查询参数
     */
    CustomPeriodStatisticModel customPeriodStatistic2(EsQuerymodel esQuerymodel);

    Map<String,Object> energyStatisticsByDeviceCode(EsQuerymodel esQuerymodel);

    /**
     * 顺丰设备监测能耗分析
     * @param esQuerymodel
     * @return
     */
    SfQueryModelResult energyAnalyzeBySpace(EsQuerymodel esQuerymodel);

    /**
     * 顺丰环境监测能耗分析
     * @param esQuerymodel
     * @return
     */
    SfQueryModelResult energyAnalyzeByRoleAuthority(EsQuerymodel esQuerymodel);

    /**
     * 根据时间范围获取索引
     * 示例："2021-06-27 20:17:28", "2021-08-27 20:17:28"
     * 结果：deviceflow-202106,deviceflow-202107,deviceflow-202108
     * @param startTime
     * @param endTime
     * @return
     */
    String getIndicesListByDate(String startTime, String endTime);

    /**
     * 根据条件从ES查询数据进行分组
     * 时间周期ES数据-》支持租户、设备、采集类型分组-》聚合类型统计
     * @param requestModel 入参对象
     * @return 出参统一对象
     */
    List<Map<String, Object>> getDeviceCollectDataAggFromEs(RequestModel<EsDeviceCollectModel> requestModel);

    /**
     * 根据前端的查询参数，直接查询es，可求聚合，灵活查询，前端查询参数直接导入请求es
     * @param paramMap
     * @param index 索引
     * @return
     */
    Map<String, Object> getDeviceCollectDataAggFromEs2(Map<String, Object> paramMap, String index);

    /**
     * 根据设备，分组统计各设备在查询时间内的能耗
     *
     * @param deviceQueryVo 查询对象vo
     * @return 统计结果
     */
    Map<String, Object> statisticsEnergyGroupByDevice(DeviceQueryVo deviceQueryVo);

    /**
     * 根据设备，分组统计各设备在查询时间内的能耗,求设备排名前n的
     * @param deviceQueryVo
     * @return
     */
    HashMap<String, BigDecimal> statisticsEnergyGroupByDeviceTopN(DeviceQueryVo deviceQueryVo);

//    @Scheduled(cron = "0 0 23 * * ?")
    boolean collectStatisticsEnergyGroupByDeviceByTimeSchedule();

    /**
     * 定时采集设备能耗,根据设备记录每天的
     * @param deviceQueryVo
     * @return
     */
    Map collectStatisticsEnergyGroupByDeviceByTime(DeviceQueryVo deviceQueryVo);

    IPage<AiCameraVo> queryAiCamera(RequestModel<AiCameraVo> aiCameraVo);

    IPage<AiCameraVo> queryAiAlarm(RequestModel<AiCameraVo> aiCameraVo);

    /**
     * 根据设备，分组统计各设备在查询时间内的能耗,根据时间各设备的折线图
     *
     * @param deviceQueryVo 查询参数
     * @return
     */
    Map<String, LinkedHashMap> statisticsEnergyGroupByDeviceByTime(DeviceQueryVo deviceQueryVo);

    Map<String, LinkedHashMap> statisticsEnergyGroupByDeviceByTime2(DeviceQueryVo deviceQueryVo);

    /**
     * 根据设备列表，项目id,消息类型查询设备的流水
     * @param projectId
     * @param tenantId
     * @param deviceCodes
     * @param msgType
     * @return
     */
    SearchHits getDeviceDataListFromESByMsgTypeAndDeviceCodes(String projectId, String tenantId,
        List<String> deviceCodes, Integer msgType);
}
